#ifndef _UHCI_H
#define _UHCI_H 1

#include"usb.h"

//  invalid QH, TD; means last QH , TD
#define  TerminateFlag  0x01
  
#define  QHFlag         0x02
#define  DepthFirstFlag 0x04

#define  ActiveStatus         0x800000
#define  StalledStatus        0x400000
#define  DataBufferError    0x200000
#define  BabbleDetected    0x100000
#define  NAKReceived        0x80000
#define  CRCTimeOutError 0x40000
#define  BitstuffError         0x20000

#define  C_ERR             0x8000000
#define  LowSpeed       0x4000000
#define  IOC                  0x1000000
#define  DataToggle     0x80000

// UHCI register
#define USBCMD     0x00
#define USBSTS      0x02
#define USBINTR     0x04
#define FRNUM       0x06
#define FLBASEADD 0x08
#define SOF             0x0c
#define PORTBASE 0x10
#define PORT1        0x10
#define PORT2        0x12

//# USBCMD     
#define RS     0x01
#define HCRESET 0x02
#define GRESET 0x04


//#PORT1 PORT2

//Current Connect Status RO.
#define  CCS   0x01
//Connect Status Change R/WC.
#define  CSC   0x02
//Port Enabled/Disabled R/W.
#define  PED   0x04
//Port Enable/Disable Change R/WC.
#define  PEDC 0x08
//Low Speed Device Attached RO.
#define  LSDA 0x100
//Port Reset R/W.
#define  PR      0x200



// UHCI area.................

/*
                                                                     3 2  1 0
        -----------------------------------------------------------
        |                   Queue Head Link Pointer       |0|0|Q|T|
        -----------------------------------------------------------

                                                                      3 2  1 0
        -----------------------------------------------------------
        |                   Queue Element Link Pointer    |0|R|Q|T|
        -----------------------------------------------------------
*/

typedef struct QH{
	DWORD   HeadLink;
	DWORD   ElementLink;
	DWORD   WORD1;    // QH must keep 16-byte align.
	DWORD   WORD2;
}QHtype;

typedef  
struct UHCIDescriptor
{
	QHtype   QH1ms;
	QHtype   QH2ms;
	QHtype   QH8ms;	

	BYTE       buffer1[256];
}UHCIDescriptorType;

typedef struct  TD TDtype;

/*
                                                           3 2  1 0
        -----------------------------------------------------------
        |                   Link Pointer                  |0|Vf|Q|T|
        -----------------------------------------------------------

         3130          23    16 15     11 10                      0
        -----------------------------------------------------------
        |R  | |       | Status |    R    |     ActLen              |                           
        -----------------------------------------------------------		

        31          2120 1918     1514           8 7              0                                                            
        -----------------------------------------------------------
        |   MaxLen    |R|D| EndPt  | Dev Addr     |       PID      |
        -----------------------------------------------------------

        31                                                        0                                                           
        -----------------------------------------------------------
        |                  Buffer Pointer                          |
        -----------------------------------------------------------       
*/
struct  TD {
	  DWORD  LinkPointer;
	  DWORD  ControlStatus;
	  DWORD  token;
	  DWORD  BufferPoint;
};




//procedure declaration
void UHCI_ControllerInitial(void * pHC);
//void initUHCIDev(HCStrucType * pHC,BYTE portIndex);


//
//Usage:  control transfer type
//IN:      
//          DeviceInfoPtr: device information pointer
//          RequstFormatType: request type needed to transmint 
//OUT:
//          status   --- return status TD phase 's state
//                      1---stalled  ; 0 ----ok.
//note: 
//          if want to transmit data , please place it in UHCIDescriptor.buffer1;
//          receve data after transation also put it in UHCIDescriptor.buffer1;
//
//          toggle value accord to USB 2.0 8.5.3 chapter
//          
BYTE UHCI_ControlTransfer(DeviceInfoPtr ptr,  RequstFormatType * RFPtr);


//
//Usage: bulk transfer type
//IN:
//        DIPtr:  device info pointer
//        direction: 0 --host to device;  1-- device to host
//        bufferPtr: data buffer to send
//        length: data length
//        ToggleValue:refer to usb2.0 8.5.2 chapter For bulk read, buld write, data begins with 0, alter each success transfer.

//        TransLength: actual transfer length, byte unit.
//OUT:
//        status:  0--ok
//                    bit0: STALL
//                    bit1: time out
//                    bit2: error
//
BYTE UHCI_bulkTransfer(DeviceInfoPtr DIPtr, BYTE direction, BYTE * bufferPtr,WORD length,WORD * TransLength);


/******************************************************************************
    Function:
        UHCI_interruptTransfer

    Description:
	UHCI bulk tansfer type

    Entry:
	DIPtr --  device description
	direction -- data transfer direction
       bufferPtr: data buffer to send or received
       length-- data length
       ToggleValue--refer to usb2.0 8.5.2. For bulk read, buld write, data begins with 0, alter each success transfer.
       TransLength-- actual transfer length, byte unit.
	
    Exit:
        status    0 ----ok.
                    bit0: STALL
                    bit1: time out
                    bit2: error

******************************************************************************/
BYTE UHCI_interruptTransfer(DeviceInfoPtr DIPtr, BYTE direction, BYTE * bufferPtr,WORD length,WORD *TransLength);
BYTE * UHCI_pointToDevBuffer(DeviceInfoPtr ptr);
void UHCI_DevPortInit(DeviceInfoPtr ptr,BYTE portIndex);





#endif
